package edu.gatech.startrader.gui;

import java.awt.BorderLayout;
import java.awt.Frame;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;

import edu.gatech.startrader.player.Player;
import edu.gatech.startrader.trade.TradeGood;
import edu.gatech.startrader.universe.Planet;

public class TradeScreen extends JDialog {

	private final JPanel contentPanel = new JPanel();
	private Player player;
	private Planet tradeEntity;
	private JTable tradeEntityTable;
	private JTable playerTable;
	private JLabel playerCreditsJLabel;
	private JLabel remainingCargoSpaceLabel;
	private JScrollPane scrollPane;
	private JScrollPane scrollPane_1;
	private JLabel lblDoubleClickTo;
	
	public static void showTradeScreen(Frame owner, Player play, Planet planet)
	{
		TradeScreen dialog = new TradeScreen(owner, true, play, planet);
		dialog.setVisible(true);
		return;
	}

	/**
	 * Create the dialog.
	 * @wbp.parser.constructor
	 */
	@SuppressWarnings("serial")
	public TradeScreen(Frame owner, boolean modal, Player play, Planet trade) 
	{
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
        }
		setTitle("Marketplace");
		player = play;
		tradeEntity = trade;
		setBounds(100, 100, 716, 150 + TradeGood.values().length * 20);
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.WEST);
		GridBagLayout gbl_contentPanel = new GridBagLayout();
		gbl_contentPanel.columnWidths = new int[]{30, 300, 300, 0};
		gbl_contentPanel.rowHeights = new int[]{38, 13 + TradeGood.values().length * 18, 0, 0, 0};
		gbl_contentPanel.columnWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
		gbl_contentPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		
		contentPanel.setLayout(gbl_contentPanel);
		{
			JLabel lblNewLabel = new JLabel(player.getName());
			GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
			gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
			gbc_lblNewLabel.gridx = 1;
			gbc_lblNewLabel.gridy = 0;
			contentPanel.add(lblNewLabel, gbc_lblNewLabel);
		}
		{
			JLabel lblTradeEntity = new JLabel(tradeEntity.getName() + ((tradeEntity instanceof Planet) ? " (" + ((Planet)tradeEntity).getTechLevel().toString() + ") " :  ""));
			
			GridBagConstraints gbc_lblTradeEntity = new GridBagConstraints();
			gbc_lblTradeEntity.insets = new Insets(0, 0, 5, 0);
			gbc_lblTradeEntity.gridx = 2;
			gbc_lblTradeEntity.gridy = 0;
			contentPanel.add(lblTradeEntity, gbc_lblTradeEntity);
		}
		{
			Object[][] tableArray = new Object[TradeGood.values().length][3];
			for(int i = 0; i < tableArray.length; i++)
			{
				tableArray[i][0] = TradeGood.values()[i].toString();
				tableArray[i][1] = player.getCargoItems(TradeGood.values()[i]);
				tableArray[i][2] = tradeEntity.getPrice(TradeGood.values()[i]);
			}
		}
		{
			Object[][] tableArray = new Object[TradeGood.values().length][3];
			for(int i = 0; i < tableArray.length; i++)
			{
				tableArray[i][0] = TradeGood.values()[i].toString();
				tableArray[i][1] = tradeEntity.getInventoryAmount(TradeGood.values()[i]);
				tableArray[i][2] = tradeEntity.getPrice(TradeGood.values()[i]);
			}
			{
				scrollPane = new JScrollPane();
				GridBagConstraints gbc_scrollPane = new GridBagConstraints();
				gbc_scrollPane.insets = new Insets(0, 0, 5, 5);
				gbc_scrollPane.fill = GridBagConstraints.BOTH;
				gbc_scrollPane.gridx = 1;
				gbc_scrollPane.gridy = 1;
				contentPanel.add(scrollPane, gbc_scrollPane);
				
				playerTable = new JTable();
				scrollPane.setViewportView(playerTable);
				playerTable.setBorder(null);
				playerTable.setShowVerticalLines(true);
				playerTable.setShowHorizontalLines(true);
				playerTable.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent arg0) {
						if (arg0.getClickCount() > 1) 
						{
							TradeGood resource = TradeGood.values()[playerTable.getSelectedRow()];
							try
							{
								if(tradeEntity.getPrice(resource) <= 0)
									throw new IllegalArgumentException(tradeEntity.getName() + " cannot buy from you " + resource.toString() + " because it is not technologically advanced enough to use " + resource.toString() + ".");
								sell(resource, Integer.parseInt(JOptionPane.showInputDialog(null, "How many " + resource + " do you want to sell?")));
							}
							catch(IllegalArgumentException iae)
							{
								if(!iae.getMessage().equals("null"))
									JOptionPane.showMessageDialog(null, iae.getMessage(), "Problem!", JOptionPane.WARNING_MESSAGE);
							}
							catch(Throwable t)
							{
								
							}
						}
						
					}
				});
				tableArray = new Object[TradeGood.values().length][2];
				for(int i = 0; i < tableArray.length; i++)
				{
					tableArray[i][0] = TradeGood.values()[i].toString();
					tableArray[i][1] = player.getCargoItems(TradeGood.values()[i]);
				}
				playerTable.setModel(new DefaultTableModel(
					tableArray,
					new String[] {
						"Resource", "Quantity"
					}
				) {
					Class[] columnTypes = new Class[] {
						String.class, Object.class
					};
					public Class getColumnClass(int columnIndex) {
						return columnTypes[columnIndex];
					}
					boolean[] columnEditables = new boolean[] {
							false, false
					};
					public boolean isCellEditable(int row, int column) {
						return columnEditables[column];
					}
				});
				playerTable.getColumnModel().getColumn(0).setPreferredWidth(65);
			}
		}
		{
			scrollPane_1 = new JScrollPane();
			GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
			gbc_scrollPane_1.insets = new Insets(0, 0, 5, 0);
			gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
			gbc_scrollPane_1.gridx = 2;
			gbc_scrollPane_1.gridy = 1;
			contentPanel.add(scrollPane_1, gbc_scrollPane_1);
			tradeEntityTable = new JTable();
			scrollPane_1.setViewportView(tradeEntityTable);
			tradeEntityTable.setShowVerticalLines(true);
			tradeEntityTable.setShowHorizontalLines(true);
			tradeEntityTable.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					if (e.getClickCount() > 1) 
					{
						TradeGood resource = TradeGood.values()[tradeEntityTable.getSelectedRow()];
						try
						{
							if(tradeEntity.getPrice(resource) <= 0)
								throw new IllegalArgumentException(tradeEntity.getName() + " cannot sell you " + resource.toString() + " because it is not technologically advanced enough to produce " + resource.toString() + ".");
							buy(resource, Integer.parseInt(JOptionPane.showInputDialog(null, "How many " + resource + " do you want to buy?")));
						}
						catch(IllegalArgumentException iae)
						{
							if(!iae.getMessage().equals("null"))
								JOptionPane.showMessageDialog(null, iae.getMessage(), "Problem!", JOptionPane.WARNING_MESSAGE);
						}
						catch(Throwable t)
						{
							
						}
					}
				}
			});
			Object[][] tableArray = new Object[TradeGood.values().length][2];
			for(int i = 0; i < tableArray.length; i++)
			{
				tableArray[i][0] = tradeEntity.getInventoryAmount(TradeGood.values()[i]);
				tableArray[i][1] = tradeEntity.getPrice(TradeGood.values()[i]);
			}
			tradeEntityTable.setModel(new DefaultTableModel(
				tableArray,
				new String[] {
					"Quantity", "Price"
				}
			) {
				Class[] columnTypes = new Class[] {
					String.class, Object.class
				};
				public Class getColumnClass(int columnIndex) {
					return columnTypes[columnIndex];
				}
				boolean[] columnEditables = new boolean[] {
						false, false
				};
				public boolean isCellEditable(int row, int column) {
					return columnEditables[column];
				}
			});
			tradeEntityTable.getColumnModel().getColumn(0).setPreferredWidth(64);
		}
		{
			playerCreditsJLabel = new JLabel("Credits: " + player.getCredits());
			GridBagConstraints gbc_playerCreditsJLabel = new GridBagConstraints();
			gbc_playerCreditsJLabel.anchor = GridBagConstraints.WEST;
			gbc_playerCreditsJLabel.insets = new Insets(0, 0, 5, 5);
			gbc_playerCreditsJLabel.gridx = 1;
			gbc_playerCreditsJLabel.gridy = 2;
			contentPanel.add(playerCreditsJLabel, gbc_playerCreditsJLabel);
		}
		{
			remainingCargoSpaceLabel = new JLabel("Remaining Cargo Space: " + player.remainingCargoSpace());
			GridBagConstraints gbc_remainingCargoSpaceLabel = new GridBagConstraints();
			gbc_remainingCargoSpaceLabel.insets = new Insets(0, 0, 5, 0);
			gbc_remainingCargoSpaceLabel.anchor = GridBagConstraints.WEST;
			gbc_remainingCargoSpaceLabel.gridx = 2;
			gbc_remainingCargoSpaceLabel.gridy = 2;
			contentPanel.add(remainingCargoSpaceLabel, gbc_remainingCargoSpaceLabel);
		}
		{
			JPanel buttonPane = new JPanel();
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				GridBagLayout gbl_buttonPane = new GridBagLayout();
				gbl_buttonPane.columnWidths = new int[]{650, 0, 45, 0};
				gbl_buttonPane.rowHeights = new int[]{28, 0};
				gbl_buttonPane.columnWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
				gbl_buttonPane.rowWeights = new double[]{0.0, Double.MIN_VALUE};
				buttonPane.setLayout(gbl_buttonPane);
			}
			JButton okButton = new JButton("OK");
			okButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
			            setVisible(false);
			            dispose();
				}
			});
			{
				lblDoubleClickTo = new JLabel("Double click table to buy/sell! (Left: Buy, Right: Sell)");
				GridBagConstraints gbc_lblDoubleClickTo = new GridBagConstraints();
				gbc_lblDoubleClickTo.insets = new Insets(0, 0, 0, 5);
				gbc_lblDoubleClickTo.gridx = 0;
				gbc_lblDoubleClickTo.gridy = 0;
				buttonPane.add(lblDoubleClickTo, gbc_lblDoubleClickTo);
			}
			okButton.setActionCommand("OK");
			GridBagConstraints gbc_okButton = new GridBagConstraints();
			gbc_okButton.insets = new Insets(0, 0, 0, 5);
			gbc_okButton.anchor = GridBagConstraints.NORTHWEST;
			gbc_okButton.gridx = 1;
			gbc_okButton.gridy = 0;
			buttonPane.add(okButton, gbc_okButton);
			getRootPane().setDefaultButton(okButton);
		}
		repaint();
	}

	/**
	 * FIrsts checks that the player can buy successfully from the TradeEntity, 
	 * if it can, it will complete the transaction.
	 * @param resource the resource to buy
	 * @param amount how many to buy
	 * @throws IllegalArgumentException if 
	 */
	public void buy(TradeGood resource, int amount) throws IllegalArgumentException
	{
		if(amount > player.remainingCargoSpace())
			throw new IllegalArgumentException("You cannot buy more " + resource.toString() + " than you have cargo space for!");
		if(amount > tradeEntity.getInventory().getAmount(resource))
			throw new IllegalArgumentException("You cannot buy more " + resource.toString() + " from " + tradeEntity.getName() + " than it owns!");
		int totalCreditsCost = tradeEntity.getPrice(resource) * amount;
		if(totalCreditsCost > player.getCredits())
			throw new IllegalArgumentException("You cannot pay more credits than you have!");
		tradeEntity.buy(resource, amount, player);
		repaint();
	}

	/**
	 * FIrsts checks that the player can sell successfully to the TradeEntity, 
	 * if it can, it will complete the transaction.
	 * @param resource which resource to sell
	 * @param amount how much to sell
	 * @throws IllegalArgumentException if selling is not possible, will be thrown
	 */
	public void sell(TradeGood resource, int amount) throws IllegalArgumentException
	{
		if(amount > player.getCargoItems(resource))
			throw new IllegalArgumentException("You cannot sell more " + resource.toString() + " than you have!");
		int totalCreditsCost = tradeEntity.getPrice(resource) * amount;
		tradeEntity.sell(resource, amount, player);
		repaint();
	}
	
	/**
	 * Updates all the information every time the dialong repaints
	 */
	public void repaint()
	{
		TradeGood[] goods = TradeGood.values();
		for(int i = 0; i < goods.length; i++)
		{
			playerTable.setValueAt(player.getCargoItems(goods[i]), i, 1);
			tradeEntityTable.setValueAt(tradeEntity.getInventoryAmount(goods[i]), i, 0);
			tradeEntityTable.setValueAt(tradeEntity.getPrice(goods[i]), i, 1);
			if(tradeEntity.getPrice(goods[i]) == 0)
			{
				tradeEntityTable.setValueAt('-', i, 0);
				tradeEntityTable.setValueAt('-', i, 1);
			}
		}
		playerCreditsJLabel.setText("Credits: " + player.getCredits());
		remainingCargoSpaceLabel.setText("Remaining Cargo Space: " + player.remainingCargoSpace());
		super.repaint();
	}
}
